<template>
  <div class="sortTemplate">
    <div class="btns">
      <div class="left">
        <el-button type="primary" class="btn" @click="onExport">导出</el-button>
        <el-button
          type="danger"
          class="btn"
          @click="onAddTable"
          v-if="isDialog"
        >
          添加到列表
        </el-button>
      </div>
      <div class="title">{{ curTable.name }}</div>
      <div class="right">
        <el-radio-group v-model="radio" @change="typeChangeHandle">
          <el-radio-button :label="1">表格</el-radio-button>
          <el-radio-button :label="2">图表</el-radio-button>
        </el-radio-group>
      </div>
    </div>
    <div v-if="sortObj">
      <el-table
        :data="sortList"
        border
        :height="tableHeight"
        v-show="radio == 1"
      >
        <el-table-column
          label="类别"
          prop="label"
          width="100"
          align="center"
        ></el-table-column>
        <template v-for="sub in subjectOptions">
          <el-table-column
            #default="{ row }"
            :label="sub.scoreKey"
            :key="sub.key"
            align="center"
          >
            {{ sortObj[sub.key] ? sortObj[sub.key][row.key] : '' }}
            <span v-if="isShowName && row.listKey">
              ：{{ sortObj[sub.key][row.listKey] | toList }}
            </span>
          </el-table-column>
        </template>
      </el-table>
      <div v-if="radio == 2">
        <!-- <div
          style="width: auto; height: 270px"
          id="sortScoreName"
          class="echartitem"
        ></div> -->
        <div
          style="width: auto; height: 250px"
          id="scoreRegion"
          class="echartitem"
        ></div>
        <div
          style="width: auto; height: 250px"
          id="rangRegion"
          class="echartitem"
        ></div>
        <div style="display: flex">
          <div
            style="width: 50%; height: 200px"
            id="pass"
            class="echartitem"
          ></div>
          <div
            style="width: 50%; height: 200px"
            id="excellent"
            class="echartitem"
          ></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapState, mapGetters } from 'vuex'
import baseMixin from '../base/baseMixin'
import { delectnNoFindTable } from '@/utils/utils'
export default {
  name: 'sortTemplate',
  mixins: [baseMixin],
  props: {
    tableId: {
      type: Number,
      require: true
    },
    tableHeight: {
      type: Number,
      default: 450
    },
    isDialog: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    ...mapState({
      subjectMap: state => state.subjectMap,
      tables: state => state.tables,
      isShowMenu: state => state.isShowMenu,
      totalMap: state => state.totalMap
    }),
    ...mapGetters(['curTable', 'subjectList', 'subjectObj', 'curIndex'])
  },
  watch: {
    tableId: {
      handler() {
        this.getTables()
      },
      immediate: true
    },
    isShowMenu() {
      this.echartsResize()
    }
  },
  data() {
    return {
      radio: 1,
      is150: true,
      subjectOptions: [],
      baseTable: [],
      sortList: {},
      scoreRegionList: [],
      otherList: [
        {
          label: '最高分',
          value: 0,
          key: 'maxScore',
          listKey: 'maxScoreList'
        },
        {
          label: '最低分',
          value: 0,
          key: 'minScore',
          listKey: 'minScoreList'
        },
        {
          label: '不及格数',
          value: 0,
          key: 'noPassNum',
          listKey: 'noPass'
        },
        {
          label: '及格数',
          value: 0,
          key: 'passNum',
          listKey: 'pass'
        },
        {
          label: '及格率%',
          value: 0,
          key: 'passRate'
        },
        {
          label: '优秀数',
          value: 0,
          key: 'excellentNum',
          listKey: 'excellent'
        },
        {
          label: '优秀率%',
          value: 0,
          key: 'excellentRate'
        },
        {
          label: '与考人数',
          value: 0,
          key: 'peopleNum'
        }
      ],
      rangRegionList: [],
      averageList: [
        {
          label: '平均分',
          value: 0,
          key: 'average'
        },
        {
          label: '均分人数',
          value: 0,
          key: 'averageNum',
          listKey: 'averageList'
        }
      ],
      sortObj: null,
      isTable: true,
      isShowName: false,
      echarts: {
        scoreRegion: null,
        rangRegion: null,
        pass: null,
        excellent: null
      }
    }
  },
  filters: {
    toList(val) {
      if (!val) return
      if (Array.isArray(val)) {
        return val.map(item => item.name).join('、')
      } else {
        return val.name || ''
      }
    }
  },
  destroyed() {
    this.destroyedEchart()
  },
  methods: {
    getTables() {
      this.curIndex
      let res = this.tables.find(v => v.id == this.tableId)
      if (!res) {
        this.isTable = false
        delectnNoFindTable()
        return false
      } else {
        this.baseTable = res
        const column = Object.keys(res.data[0])
        const subject = this.subjectMap.filter(item => {
          return column.includes(item.name)
        })
        let total = this.totalMap.reverse().find(item => {
          return column.includes(item.name)
        })
        this.subjectOptions = [...subject, { ...total }]
      }
      this.getRowName()
    },
    getRowName() {
      if (!this.isTable) return false
      this.scoreRegionList = this.getScoreRegionList()
      this.rangRegionList = this.getRangRegionList()
      this.sortList = [
        ...this.scoreRegionList,
        ...this.otherList,
        ...this.rangRegionList,
        ...this.averageList
      ]
      this.init()
    },
    // 获取分数区间
    getScoreRegionList() {
      let scoreList = []
      for (let i = 14; i >= 0; i--) {
        let startScore = i * 10
        let endScore = startScore + 9
        scoreList.push({
          label: `${startScore}-${endScore}`,
          value: 0,
          key: `score${startScore}to${endScore}Num`,
          listKey: `score${startScore}to${endScore}`
        })
      }
      if (this.is150) {
        scoreList[0].label = '140-150'
      } else {
        scoreList.splice(0, 5)
        scoreList[0].label = '90-100'
      }
      return scoreList
    },
    // 获取排名区间
    getRangRegionList() {
      let rangList = [
        {
          label: '前10名',
          value: 0,
          key: 'top10Num',
          isAdd: true
        }
      ]
      for (let i = 50; i <= 400; i += 50) {
        rangList.push({
          label: `前${i}名`,
          value: 0,
          key: `top${i}Num`,
          listKey: `top${i}`,
          isAdd: true
        })
      }
      rangList.push({
        label: '400名后',
        value: 0,
        key: 'otherTopNum',
        listKey: 'otherTop'
      })
      return rangList
    },
    init() {
      let sortObj = {}
      this.subjectOptions.forEach(item => {
        sortObj[item.key] = this.classDataHandle(item)
      })
      this.sortObj = sortObj
      this.typeChangeHandle()
    },
    classDataHandle(subConfig) {
      const table = this.baseTable
      const list = table.sortObj[subConfig.scoreKey]
      const rankList = table.sortObj[subConfig.rankKey]
      if (!list || !rankList) return null
      // this.scoreList = list.sort((a, b) => {
      //   return b.score - a.score
      // })
      const is150 = subConfig.fullScore === 150
      const isTotal = subConfig.isTotal
      let sortObj = {
        score0to9Num: isTotal ? '' : 0,
        score10to19Num: isTotal ? '' : 0,
        score20to29Num: isTotal ? '' : 0,
        score30to39Num: isTotal ? '' : 0,
        score40to49Num: isTotal ? '' : 0,
        score50to59Num: isTotal ? '' : 0,
        score60to69Num: isTotal ? '' : 0,
        score70to79Num: isTotal ? '' : 0,
        score80to89Num: isTotal ? '' : 0,
        score90to99Num: isTotal ? '' : 0,
        score100to109Num: !is150 || isTotal ? '' : 0,
        score110to119Num: !is150 || isTotal ? '' : 0,
        score120to129Num: !is150 || isTotal ? '' : 0,
        score130to139Num: !is150 || isTotal ? '' : 0,
        score140to149Num: !is150 || isTotal ? '' : 0,
        maxScore: 0, //最高分
        maxScoreList: [],
        minScore: 0, //最低分
        minScoreList: [],
        pass: [],
        passNum: 0, //及格数
        noPass: [],
        noPassNum: 0, // 不及格数
        passRate: 0, // 及格率
        excellent: [],
        excellentNum: 0, //优秀数
        excellentRate: 0, //优秀率
        peopleNum: list.length, //与考人数
        top10: [],
        top50: [],
        top100: [],
        top150: [],
        top200: [],
        top250: [],
        top300: [],
        top350: [],
        top400: [],
        otherTop: [],
        average: 0, //平均分
        averageList: [],
        averageNum: 0 //均分人数
      }
      let totalScore = 0
      let passScore = subConfig.fullScore * 0.6
      let excellentScore = subConfig.fullScore * 0.85
      list.forEach(item => {
        const score = isNaN(item.score) ? 0 : parseFloat(item.score)
        !isTotal && this.getScoreRange(item, sortObj, is150)
        // 总分
        totalScore += score
        // 获得最高分
        if (score > sortObj.maxScore) {
          sortObj.maxScore = score
          sortObj.maxScoreList = [item]
        }
        // 获取最低分
        if (score < sortObj.minScore) {
          sortObj.minScore = score
          sortObj.minScoreList = [item]
        }
        // 及格
        if (score >= passScore) {
          sortObj.pass.push(item)
        } else {
          sortObj.noPass.push(item)
        }
        // 优秀
        if (score >= excellentScore) {
          sortObj.excellent.push(item)
        }
      })
      if (subConfig.isTotal) {
        ;[
          'passNum',
          'noPassNum',
          'passRate',
          'excellentNum',
          'excellentRate'
        ].forEach(key => {
          sortObj[key] = ''
        })
      } else {
        sortObj.passNum = sortObj.pass.length
        sortObj.noPassNum = sortObj.noPass.length
        sortObj.passRate = (
          (sortObj.passNum / sortObj.peopleNum) *
          100
        ).toFixed(2)
        sortObj.excellentNum = sortObj.excellent.length
        sortObj.excellentRate = (
          (sortObj.excellentNum / sortObj.peopleNum) *
          100
        ).toFixed(2)
      }

      // 平均分
      sortObj.average = (totalScore / sortObj.peopleNum).toFixed(2)
      // 获取均分人数
      list.forEach(item => {
        if (item.score >= sortObj.average) {
          sortObj.averageList.push(item)
        }
      })
      sortObj.averageNum = sortObj.averageList.length

      // 排名
      rankList.forEach(item => {
        if (item.score > 0 && item.score <= 10) {
          sortObj.top10.push(item)
        } else if (item.score > 10 && item.score <= 50) {
          sortObj.top50.push(item)
        } else if (item.score > 50 && item.score <= 100) {
          sortObj.top100.push(item)
        } else if (item.score > 100 && item.score <= 150) {
          sortObj.top150.push(item)
        } else if (item.score > 150 && item.score <= 200) {
          sortObj.top200.push(item)
        } else if (item.score > 200 && item.score <= 250) {
          sortObj.top250.push(item)
        } else if (item.score > 250 && item.score <= 300) {
          sortObj.top300.push(item)
        } else if (item.score > 300 && item.score <= 350) {
          sortObj.top350.push(item)
        } else if (item.score > 350 && item.score <= 400) {
          sortObj.top400.push(item)
        } else {
          sortObj.otherTop.push(item)
        }
      })
      let scoreArr = [10, 50, 100, 150, 200, 250, 300, 350, 400]
      scoreArr.forEach((v, i) => {
        sortObj[`top${v}Num`] =
          sortObj[`top${v}`].length + (sortObj[`top${scoreArr[i - 1]}Num`] || 0)
      })
      sortObj.otherTopNum = sortObj.otherTop.length
      return sortObj
    },
    // 获取分段人数
    getScoreRange(item, obj, is150 = false) {
      let fromNum = parseInt(item.score / 10) * 10
      if (!is150 && fromNum == 10) fromNum = 9
      if (is150 && fromNum == 15) fromNum = 14
      let toNum = fromNum + 9
      if (!obj[`score${fromNum}to${toNum}`]) {
        obj[`score${fromNum}to${toNum}`] = []
      }
      obj[`score${fromNum}to${toNum}`].push(item)
      obj[`score${fromNum}to${toNum}Num`] =
        obj[`score${fromNum}to${toNum}`].length
    },
    onExport() {
      const table = this.tableHandle()
      this.baseExportExcel(table)
    },
    // 添加到列表
    onAddTable() {
      const table = {
        id: Date.now(),
        column: [],
        name: `${this.baseTable.name}-科目分析表`,
        className: this.baseTable.className,
        isCompare: false,
        template: 'sortTemplate',
        extend: {
          tableId: this.tableId
        }
      }
      this.$store.commit('addTable', table)
      this.$store.commit('setCurTableId', table.id)
      this.$emit('onAddTable')
    },
    tableHandle() {
      const data = []
      this.$el
        .getElementsByTagName('table')[1]
        .childNodes[1].childNodes.forEach(item => {
          if (item.tagName !== 'TR') return
          let _item = {}
          let textContent = item.childNodes[0].textContent.trim()
          if (textContent == '类别') return
          _item['类别'] = textContent
          this.subjectOptions.forEach((n, index) => {
            _item[n.name] = item.childNodes[index + 1].textContent.trim()
          })
          data.push(_item)
        })
      const table = {
        id: Date.now(),
        column: Object.keys(data[0]),
        data: data,
        name: `${this.baseTable.name}-科目分析表`,
        className: this.baseTable.className,
        isCompare: false,
        isScore: false,
        template: 'sortTemplate'
      }
      return table
    },
    echartInit() {
      this.$nextTick(() => {
        // this.echartsScoreNameInit()
        this.echartsScoreRegionInit()
        this.echartsRangRegionInit()
        this.echartsPassInit()
        this.echartsexcellentInit()
      })
    },
    typeChangeHandle() {
      if (!this.sortObj) {
        this.destroyedEchart()
        return
      }
      this.radio == 1 ? this.destroyedEchart() : this.echartInit()
    },
    // 分数折线表
    echartsScoreNameInit() {
      this.echarts.sortScoreName = this.$echarts.init(
        document.getElementById('sortScoreName')
      )
      const _this = this
      const options = {
        title: {
          text: '成绩排序表'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'line'
          }
        },
        xAxis: {
          name: '姓名',
          type: 'category',
          data: this.scoreList.map(item => item.name),
          axisLabel: { interval: 0, rotate: 45 }
        },
        yAxis: {
          name: '分数',
          type: 'value',
          nameTextStyle: {
            padding: [0, 50, 5, 0]
          }
        },
        series: [
          {
            name: '分数',
            data: this.scoreList.map(item => item.score),
            type: 'line',
            markPoint: {
              data: [
                {
                  type: 'max',
                  name: '最高分'
                },
                {
                  type: 'min',
                  name: '最低分'
                }
              ]
            },
            markLine: {
              data: [
                {
                  type: 'average',
                  name: '平均分'
                }
              ],
              label: {
                formatter(item) {
                  return `${item.name}：${item.value}\n均分人数：${_this.sortObj.averageNum}`
                }
              }
            }
          }
        ]
      }
      this.echarts.sortScoreName.setOption(options)
    },
    // 分数段柱状图
    getSeriesData(type, subject) {
      return {
        name: subject.scoreKey,
        data: this.sortObj[subject.key]
          ? this[type].map(item => this.sortObj[subject.key][item.key])
          : [],
        type: 'bar',
        label: {
          show: true
        }
        // showBackground: true
      }
    },
    echartsScoreRegionInit() {
      const series = [],
        legendSelected = {}
      this.subjectMap.forEach(item => {
        if (this.sortObj[item.key]) {
          legendSelected[item.scoreKey] = false
          series.push(this.getSeriesData('scoreRegionList', item))
        }
      })
      ;['语文', '数学', '英语'].forEach(k => (legendSelected[k] = true))
      this.echarts.scoreRegion = this.$echarts.init(
        document.getElementById('scoreRegion')
      )
      const options = {
        title: {
          text: '成绩分析表'
        },
        toolbox: {
          show: true,
          feature: {
            magicType: { type: ['bar', 'line'] },
            saveAsImage: {}
          }
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        legend: {
          show: true,
          left: 'center',
          selected: legendSelected
        },
        grid: {
          true: false
        },
        xAxis: {
          name: '分数',
          type: 'category',
          data: this.scoreRegionList.map(item => item.label),
          axisLabel: { interval: 0, rotate: 20 }
        },
        yAxis: {
          name: '人数',
          type: 'value'
        },
        series: series
      }
      this.echarts.scoreRegion.setOption(options)
    },
    // 名次段柱状图
    echartsRangRegionInit() {
      const series = []
      const legendSelected = {}
      this.subjectOptions.forEach((item, index) => {
        legendSelected[item.scoreKey] = false
        if (index == 0) {
          legendSelected[item.scoreKey] = true
        }
        series.push(this.getSeriesData('rangRegionList', item))
      })
      this.totalMap.reverse().find(item => {
        if (this.sortObj[item.key]) {
          legendSelected[item.scoreKey] = true
          return true
        }
      })
      this.echarts.scoreRegion = this.$echarts.init(
        document.getElementById('scoreRegion')
      )
      this.echarts.rangRegion = this.$echarts.init(
        document.getElementById('rangRegion')
      )
      const options = {
        title: {
          text: '名次分析表'
        },
        toolbox: {
          show: true,
          feature: {
            magicType: { type: ['bar', 'line'] },
            saveAsImage: {}
          }
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        legend: {
          show: true,
          left: 'center',
          selected: legendSelected
        },
        xAxis: {
          name: '名次',
          type: 'category',
          data: this.rangRegionList.map(item => item.label),
          axisLabel: { interval: 0, rotate: 0 }
        },
        yAxis: {
          name: '人数',
          type: 'value'
        },
        series: series
      }
      this.echarts.rangRegion.setOption(options)
    },
    // 及格率
    echartsPassInit() {
      const seriesData = [],
        xAxisData = []
      this.subjectMap.forEach(item => {
        if (this.sortObj[item.key]) {
          seriesData.push(this.sortObj[item.key].passRate)
          xAxisData.push(item.scoreKey)
        }
      })
      this.echarts.pass = this.$echarts.init(document.getElementById('pass'))
      let options = {
        title: {
          text: '及格率'
        },
        toolbox: {
          show: true,
          feature: {
            saveAsImage: {}
          }
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'line'
          },
          formatter: '{b}：{c}%'
        },
        xAxis: {
          name: '科目',
          type: 'category',
          data: xAxisData,
          axisLabel: { interval: 0, rotate: 0 }
        },
        yAxis: {
          name: '%'
        },
        series: [
          {
            type: 'line',
            data: seriesData,
            label: {
              show: true
            }
          }
        ]
        // legend: {
        //   show: true,
        //   zlevel: 0,
        //   z: 2,
        //   left: 'center'
        // }
      }
      this.echarts.pass.setOption(options)
    },
    // 优秀率
    echartsexcellentInit() {
      const seriesData = [],
        xAxisData = []
      this.subjectMap.forEach(item => {
        if (this.sortObj[item.key]) {
          xAxisData.push(item.scoreKey)
          seriesData.push(this.sortObj[item.key].excellentRate)
        }
      })
      this.echarts.excellent = this.$echarts.init(
        document.getElementById('excellent')
      )
      const options = {
        title: {
          text: '优秀率'
        },
        toolbox: {
          show: true,
          feature: {
            saveAsImage: {}
          }
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'line'
          },
          formatter: '{b}：{c}%'
        },
        xAxis: {
          name: '科目',
          type: 'category',
          data: xAxisData,
          axisLabel: { interval: 0, rotate: 0 }
        },
        yAxis: {
          name: '%'
        },
        series: [
          {
            type: 'line',
            data: seriesData,
            label: {
              show: true
            }
          }
        ]
      }
      this.echarts.excellent.setOption(options)
    },
    // 注销
    destroyedEchart() {
      for (let k in this.echarts) {
        this.echarts[k] && this.echarts[k].dispose()
      }
    },
    echartsResize() {
      setTimeout(() => {
        for (let k in this.echarts) {
          this.echarts[k] && this.echarts[k].resize()
        }
      }, 500)
    }
  }
}
</script>

<style lang="scss" scoped>
.sortTemplate {
  position: relative;
  .btns {
    display: flex;
    padding: 10px;
    .left {
      flex-shrink: 0;
    }
    .title {
      flex: 1;
      color: #fff;
      text-align: center;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
    .right {
      margin: 0 auto;
      flex-shrink: 0;
    }
    .btn {
      margin-right: 5px;
    }
  }
  .tip {
    text-align: center;
    line-height: 60px;
    color: red;
    font-size: 16px;
  }
  .echartitem {
    border: 1px solid #e5e7eb;
    box-shadow: rgb(10 9 9 / 10%) 0px 0px 5px;
    margin: 5px;
    border-radius: 5px;
    background: #fff;
  }
  ::v-deep {
    .el-tabs__header {
      margin: 13px 10px -1px;
    }
    .el-tabs__item {
      color: #409eff;
      :hover {
        color: #ff4545;
      }
    }
    .el-tabs__item.is-active {
      color: #ff4545;
    }
  }
}
</style>
